package com.by.service.impl;

import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.by.bean.CartInfo;
import com.by.bean.ShopCart;
import com.by.bean.ShopCartItem;
import com.by.mapper.ShopCartItemMapper;
import com.by.service.ShopCartItemService;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import java.util.*;
import java.util.concurrent.TimeUnit;

@Slf4j
@Service
public class ShopCartItemServiceImpl extends ServiceImpl<ShopCartItemMapper, ShopCartItem> implements ShopCartItemService {

    private static final String CART_KEY_PREFIX = "cart:user:";
    private static final String SKU_FIELD_PREFIX = "sku:";
    private static final String SKU_INFO_KEY_PREFIX = "sku:info:";
    private static final long CART_EXPIRE_DAYS = 7;
    private static final long SKU_INFO_EXPIRE_DAYS = 30;

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Autowired
    private ObjectMapper objectMapper;

    @Autowired
    private ShopCartItemMapper shopCartItemMapper;

    // 购物车商品数量 Hash key
    private static final String CART_COUNT_KEY = "cart:user:%s";
    // 商品信息 Hash key
    private static final String CART_SKU_KEY = "cart:sku:%s";
    // 购物车选中状态 Hash key
    private static final String CART_SELECTED_KEY = "cart:selected:%s";
    // 购物车过期时间（7天）
    private static final long CART_EXPIRE_TIME = 7 * 24 * 60 * 60;

    // 生成购物车key
    private String generateCartKey(Long userId) {
        return CART_KEY_PREFIX + userId;
    }

    // 生成商品field
    private String generateSkuField(Long skuId) {
        return SKU_FIELD_PREFIX + skuId;
    }

    // 生成商品信息key
    private String generateSkuInfoKey(Long skuId) {
        return SKU_INFO_KEY_PREFIX + skuId;
    }

    @Override
    public int addToCart(ShopCartItem cartItem) {
        try {
            log.info("添加商品到购物车 - 用户ID: {}, SKU ID: {}, 数量: {}", 
                cartItem.getUserId(), cartItem.getSkuId(), cartItem.getCount());

            // 1. 获取商品数量 Hash key
            String countKey = String.format(CART_COUNT_KEY, cartItem.getUserId());
            // 2. 获取商品信息 Hash key
            String skuKey = String.format(CART_SKU_KEY, cartItem.getSkuId());

            // 3. 存储商品信息
            try {
                redisTemplate.opsForHash().put(skuKey, "info", objectMapper.writeValueAsString(cartItem));
                redisTemplate.opsForHash().put(skuKey, "selected", "1");
            } catch (JsonProcessingException e) {
                log.error("商品信息序列化失败", e);
                return 0;
            }

            // 4. 更新商品数量
            redisTemplate.opsForHash().increment(countKey, cartItem.getSkuId().toString(), cartItem.getCount());

            // 5. 设置过期时间
            redisTemplate.expire(countKey, CART_EXPIRE_TIME, TimeUnit.SECONDS);
            redisTemplate.expire(skuKey, CART_EXPIRE_TIME, TimeUnit.SECONDS);

            log.info("商品已成功添加到购物车");
            return 1;
        } catch (Exception e) {
            log.error("添加购物车失败", e);
            return 0;
        }
    }

    @Override
    public ShopCart getCart(Long userId) {
        try {
            // 1. 获取商品数量 Hash key
            String countKey = String.format(CART_COUNT_KEY, userId);

            // 2. 获取用户购物车中的所有商品ID
            Map<Object, Object> countMap = redisTemplate.opsForHash().entries(countKey);
            if (countMap.isEmpty()) {
                return new ShopCart();
            }

            // 3. 构建购物车信息
            ShopCart cart = new ShopCart();
            cart.setUserId(userId);
            List<ShopCartItem> items = new ArrayList<>();
            long totalAmount = 0L;

            for (Map.Entry<Object, Object> entry : countMap.entrySet()) {
                String skuId = entry.getKey().toString();
                Integer count = Integer.parseInt(entry.getValue().toString());
                
                // 获取商品信息
                String skuKey = String.format(CART_SKU_KEY, skuId);
                String itemJson = (String) redisTemplate.opsForHash().get(skuKey, "info");
                String selected = (String) redisTemplate.opsForHash().get(skuKey, "selected");
                
                ShopCartItem item = objectMapper.readValue(itemJson, ShopCartItem.class);
                item.setCount(count);
                item.setChecked("1".equals(selected));
                item.setTotalFee(count * item.getPriceFee());
                
                totalAmount += item.getTotalFee();
                items.add(item);
            }

            cart.setItems(items);
            cart.setTotalAmount(totalAmount);
            return cart;

        } catch (Exception e) {
            log.error("获取购物车信息失败", e);
            return new ShopCart();
        }
    }

    @Override
    public int deleteItem(Long userId, Long skuId) {
        try {
            // 1. 获取商品数量 Hash key
            String countKey = String.format(CART_COUNT_KEY, userId);
            // 2. 获取商品信息 Hash key
            String skuKey = String.format(CART_SKU_KEY, skuId);

            // 3. 删除商品数量
            redisTemplate.opsForHash().delete(countKey, skuId.toString());
            // 4. 删除商品信息
            redisTemplate.delete(skuKey);
            return 1;
        } catch (Exception e) {
            log.error("删除购物车商品失败", e);
            return 0;
        }
    }

    @Override
    public void checkItem(Long userId, Long skuId, Boolean checked) {
        try {
            // 1. 获取商品信息 Hash key
            String skuKey = String.format(CART_SKU_KEY, skuId);
            // 2. 更新选中状态
            redisTemplate.opsForHash().put(skuKey, "selected", checked ? "1" : "0");
            // 3. 设置过期时间
            redisTemplate.expire(skuKey, CART_EXPIRE_TIME, TimeUnit.SECONDS);
        } catch (Exception e) {
            log.error("更新商品选中状态失败", e);
            throw new RuntimeException("更新商品选中状态失败", e);
        }
    }

    @Override
    public int clearCart(Long userId) {
        try {
            // 1. 获取商品数量 Hash key
            String countKey = String.format(CART_COUNT_KEY, userId);

            // 2. 获取所有商品ID
            Map<Object, Object> countMap = redisTemplate.opsForHash().entries(countKey);
            for (Object skuId : countMap.keySet()) {
                // 3. 删除商品信息
                String skuKey = String.format(CART_SKU_KEY, skuId);
                redisTemplate.delete(skuKey);
            }

            // 4. 删除商品数量
            redisTemplate.delete(countKey);
            return 1;
        } catch (Exception e) {
            log.error("清空购物车失败", e);
            return 0;
        }
    }

    @Override
    public int updateCartCount(Long userId, Long skuId, int delta) {
        log.info("更新购物车商品数量 - 用户ID: {}, SKU ID: {}, 变化量: {}", userId, skuId, delta);
        
        try {
            String countKey = String.format(CART_COUNT_KEY, userId);
            String skuKey = String.format(CART_SKU_KEY, skuId);
            
            // 先检查商品信息是否存在
            String itemJson = (String) redisTemplate.opsForHash().get(skuKey, "info");
            if (itemJson == null) {
                log.warn("商品信息不存在 - SKU ID: {}", skuId);
                return 0;
            }
            
            // 获取当前数量
            Integer currentCount = (Integer) redisTemplate.opsForHash().get(countKey, skuId.toString());
            if (currentCount == null) {
                currentCount = 0;
            }
            
            // 计算新的数量
            int newCount = currentCount + delta;
            
            // 如果数量小于等于0，则删除商品
            if (newCount <= 0) {
                deleteItem(userId, skuId);
                log.info("商品数量为0，已从购物车删除 - 用户ID: {}, SKU ID: {}", userId, skuId);
                return 1;
            }
            
            // 更新数量
            redisTemplate.opsForHash().put(countKey, skuId.toString(), newCount);
            redisTemplate.expire(countKey, CART_EXPIRE_TIME, TimeUnit.SECONDS);
            
            log.info("成功更新购物车商品数量 - 用户ID: {}, SKU ID: {}, 新数量: {}", 
                userId, skuId, newCount);
            return 1;
            
        } catch (Exception e) {
            log.error("更新购物车商品数量失败 - 用户ID: {}, SKU ID: {}", userId, skuId, e);
            return 0;
        }
    }

    @Override
    public CartInfo getCartInfo(Long userId) {
        ShopCart cart = getCart(userId);
        CartInfo cartInfo = new CartInfo();
        
        if (cart != null && !CollectionUtils.isEmpty(cart.getItems())) {
            cartInfo.setItems(cart.getItems());
            cartInfo.setTotalCount(cart.getItems().stream().mapToInt(ShopCartItem::getCount).sum());
            cartInfo.setTotalAmount(cart.getTotalAmount());
            
            // 计算已选中商品的总金额
            long checkedAmount = cart.getItems().stream()
                .filter(ShopCartItem::isChecked)
                .mapToLong(ShopCartItem::getTotalFee)
                .sum();
            cartInfo.setCheckedAmount(checkedAmount);
        }
        
        return cartInfo;
    }

    @Override
    public Integer getCartCount(Long userId) {
        try {
            String countKey = String.format(CART_COUNT_KEY, userId);
            Map<Object, Object> countMap = redisTemplate.opsForHash().entries(countKey);
            if (countMap.isEmpty()) {
                return 0;
            }
            return countMap.values().stream()
                .mapToInt(value -> Integer.parseInt(value.toString()))
                .sum();
        } catch (Exception e) {
            log.error("获取购物车商品数量失败", e);
            return 0;
        }
    }
} 